/**
 *  chdev.h - Driver model of char devices and related calls
 *
 *  Copyright (C) 2008-2010 ZhangHu
 *  All rights reserved.
 *  E-MAIL: anmnmnly@gmail.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __CHDEV_H__
#define __CHDEV_H__


#include "include/types.h"


#ifndef UNIT_DEBUG
#include "drivers/device.h"
#endif



struct chdev_operations
{
    int32 (*open)(void);
    int32 (*close)(void);
    int32 (*write)(const char_t *buf, uint32 len, loff_t loff);
    int32 (*read)(char_t *buf, uint32 len, loff_t loff);
    int32 (*ioctl)(uint32 cmd, void *arg); // return TRUE or FALSE
    void (*release)(void);                 // Called before device unregister
};



typedef struct _char_device
{
    device_t dev;                // Device node
    loff_t loff;                 // Offset of read and write
    uint32 capacity;            // Capacity of device
    struct chdev_operations *op; // Operations for char device
} chdev_t;


// Register a device to Bycore
extern int32 chdevRegister(uint8 Mid,         // Main ID
                           uint8 Sid,         // Secondary ID
                           const char_t *Name,// Device name
                           uint32 Size,       // The capacity of device.
                           struct chdev_operations *Operation);

// Unregister a device from Bycore
extern void chdevUnRegister(uint32 chdevMID, uint32 chdevSID);


extern chdev_t *CDevOpen(const char_t *name);
extern int32 CDevClose(chdev_t *Self);
extern loff_t CDevLLSeek(chdev_t *Self, loff_t Loff);
extern int32 CDevWrite(chdev_t *Self, const char_t *Buf, uint32 Len);
extern int32 CDevRead(chdev_t *Self, char_t *Buf, uint32 Len);
extern int32 CDevIoctl(chdev_t *Self, uint32 Cmd, void *Arg);


#endif

